package avicit.bdp.dds.api.utils;


import avicit.bdp.core.util.json.JSONUtils;
import avicit.bdp.dds.common.graph.DAG;
import avicit.bdp.dds.dao.entity.BloodConfigDTO;
import avicit.bdp.dds.dao.entity.ProcessDefinition;
import avicit.bdp.dds.dispatch.model.ProcessData;
import avicit.bdp.dds.dispatch.model.TaskNode;
import avicit.bdp.dds.dispatch.task.datax.DataxParameters;
import avicit.bdp.dds.dispatch.task.sql.SqlParameters;
import avicit.platform6.commons.utils.ComUtil;
import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLCreateViewStatement;
import com.alibaba.druid.sql.ast.statement.SQLTableSource;
import com.alibaba.druid.sql.visitor.SchemaStatVisitor;
import com.alibaba.druid.stat.TableStat;
import com.alibaba.druid.stat.TableStat.Name;
import com.alibaba.druid.stat.TableStat.Relationship;
import com.alibaba.druid.util.JdbcConstants;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;

/**
 * 流程数据表解析
 *
 * @author xugb
 * @date 2023/5/9 9:18
 */
public class BloodAnalyseUtils {

    private static final Logger logger = LoggerFactory.getLogger(BloodAnalyseUtils.class);

    //血缘关系解析
    public static List<BloodConfigDTO> bloodAnalyse(ProcessDefinition processDefinition) {
        List<BloodConfigDTO> bloodList = null;
        String processDefinitionJson = processDefinition.getProcessDefinitionJson();
        ProcessData processData = JSONUtils.parseObject(processDefinitionJson, ProcessData.class);
        if (processData == null) {
            return new ArrayList<>();
        }
        //数据计算
        if (processDefinition.getType() >= 7) {
            bloodList = analyseSparkFLowProcessNodeList(processData);
        } else {
            bloodList = analyseCommonProcessNodeList(processData);
        }
        //去重
        bloodList = bloodList.stream().collect(
                Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(
                                Comparator.comparing(blood -> blood.getSourceDatasourceId() + "-" + blood.getSourceTableCode() + "-" + blood.getSourceFieldCode() +
                                        blood.getTargetDatasourceId() + "-" + blood.getTargetTableCode() + "-" + blood.getTargetFieldCode() + "-" + blood.getStatus()))), ArrayList::new));
        //设置默认信息
        for (BloodConfigDTO blood : bloodList) {
            blood.setId(ComUtil.getId());
            blood.setProcessDefinitionId(processDefinition.getId());
            blood.setProjectId(processDefinition.getProjectId());
        }
        return bloodList;
    }

    private static List<BloodConfigDTO> analyseCommonProcessNodeList(ProcessData processData) {
        List<TaskNode> taskNodes = processData.getTasks();
        List<BloodConfigDTO> bloodList = new ArrayList<>();
        for (TaskNode taskNode : taskNodes) {
            List<BloodConfigDTO> list = handleCommonNode(taskNode);
            bloodList.addAll(list);
        }
        return bloodList;
    }

    private static List<BloodConfigDTO> handleCommonNode(TaskNode taskNode) {
        List<BloodConfigDTO> list = new ArrayList<>();

        if (taskNode.getType().equals("SQL")) {
            //处理SQL节点
            String params = taskNode.getParams();
            SqlParameters p = JSONUtils.parseObject(params, SqlParameters.class);
            if (StringUtils.isBlank(p.getDatasource())) {
                return list;
            }
            DbType dbType = DbType.other;
            if (StringUtils.isNotBlank(p.getType())) {
                dbType = DbType.valueOf(p.getType());
            }
            String sql = p.getSql();
            List<String> sqlList = new ArrayList<>();
            sqlList.addAll(p.getPreStatements());
            sqlList.add(sql);
            sqlList.addAll(p.getPostStatements());
            List<BloodConfigDTO> alist = handleSQLNode(sqlList, dbType, p.getDatasource());
            list.addAll(alist);

        } else if (taskNode.getType().equals("DATAX")) {
            //处理DATAX节点
            String params = taskNode.getParams();
            DataxParameters p = JSONUtils.parseObject(params, DataxParameters.class);
            BloodConfigDTO bloodConfigDTO = new BloodConfigDTO();
            bloodConfigDTO.setSourceDatasourceId(p.getDataSource());
            bloodConfigDTO.setSourceTableCode(p.getSourceTable());
            bloodConfigDTO.setTargetDatasourceId(p.getDataTarget());
            bloodConfigDTO.setTargetTableCode(p.getTargetTable());
            bloodConfigDTO.setStatus(0);
            list.add(bloodConfigDTO);
        }
        return list;
    }

    private static List<BloodConfigDTO> handleSQLNode(List<String> sqlList, DbType dbType, String datasourceId) {
        List<BloodConfigDTO> bloodList = new ArrayList<>();
        Map<String, List<String>> tempTableMap = new HashMap<>();
        Map<String, String> dataTableMap = new HashMap<>();
        Map<String, String> relationMap = new HashMap<>();
        Map<String, String> relationColumnMap = new HashMap<>();
        Map<String, String> dataColumnMap = new HashMap<>();
        for (String sql : sqlList) {
            if (StringUtils.isBlank(sql)) {
                BloodConfigDTO bloodConfigDTO = new BloodConfigDTO();
                bloodConfigDTO.setSourceDatasourceId(datasourceId);
                bloodConfigDTO.setStatus(0);
                bloodList.add(bloodConfigDTO);
                continue;
            }
            try {


                List<SQLStatement> stmtList = SQLUtils.parseStatements(sql, dbType);
                // 解析出的独立语句的个数
                for (int i = 0; i < stmtList.size(); i++) {

                    SQLStatement stmt = stmtList.get(i);

                    SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(dbType);
                    stmt.accept(visitor);
                    // 获取表名称 解析数据表之间的流向
                    logger.debug("解析数据表数据之间的流向    table names:" + visitor.getTables());
                    Map<Name, TableStat> tabmap = visitor.getTables();

                    boolean hasInsert = false;
                    String toTableId = null;
                    String toTableCode = null;
                    String toKey = null;

                    // 单独处理创建视图的sql,因为druid解析中getTable方法，不包括创建的view
                    if (stmt instanceof SQLCreateViewStatement) {
                        SQLTableSource tableSource = ((SQLCreateViewStatement) stmt).getTableSource();
                        String tableName = getTableNameFromName(tableSource.toString());

                        String key = tableName.toUpperCase();
                        //暂时放入
                        dataTableMap.put(key, key);
                        toTableCode = tableName;
                        hasInsert = true;
                        toTableId = dataTableMap.get(key);
                        toKey = key;
                        if (toTableId == null) {// 该表为临时表，或是不在数据字典中的表
                            tempTableMap.put(key, new ArrayList<String>());
                        }
                    }

                    for (Iterator iterator = tabmap.keySet().iterator(); iterator.hasNext(); ) {
                        Name name = (Name) iterator.next();
                        TableStat tableStat = tabmap.get(name);
                        String tableName = getTableNameFromName(name.getName());
                        String key = tableName.toUpperCase();
                        //暂时放入
                        dataTableMap.put(key, key);
                        logger.debug(name.toString() + " - " + tabmap.get(name).toString());
                        String tsTableName = tableStat.toString().toLowerCase();
                        if (tsTableName.contains("insert") || tsTableName.contains("create")) {
                            hasInsert = true;
                            toTableId = dataTableMap.get(key);
                            toTableCode = tableName;
                            toKey = key;
                            if (toTableId == null) {// 该表为临时表，或是不在数据字典中的表
                                tempTableMap.put(key, new ArrayList<String>());
                            }
                        } else if (hasInsert && tsTableName.contains("select")) {
                            String fromTableId = dataTableMap.get(key);
                            // 处理临时表,
                            if (toTableId == null) {
                                // 判断来源表是否是临时表，不是临时表则加入到插入表的列表中
                                if (fromTableId != null) {
                                    tempTableMap.get(toKey).add(fromTableId);
                                } else {
                                    // 还是临时表,则把临时对应的数据字典中表加入到此临时表中
                                    List<String> fromList = tempTableMap.get(toKey);
                                    if (fromList != null) {
                                        List<String> selectList = tempTableMap.get(key);
                                        if (selectList != null) {
                                            for (String select : selectList) {
                                                if (!fromList.contains(select)) {
                                                    fromList.add(select);
                                                }
                                            }
                                        }
                                    }

                                }
                                continue;
                            }
                            // 如果来源表和目标表是同一个则不保存
                            if (toTableId.equals(dataTableMap.get(key))) {
                                continue;
                            }
                            // 如果是临时表
                            if (fromTableId == null) {
                                List<String> fromTableIdList = tempTableMap.get(key);
                                if (fromTableIdList == null) {
                                    continue;
                                }
                                for (String fromId : fromTableIdList) {
                                    BloodConfigDTO bloodConfigDTO = new BloodConfigDTO();
                                    bloodConfigDTO.setSourceDatasourceId(datasourceId);
                                    bloodConfigDTO.setTargetDatasourceId(datasourceId);
                                    bloodConfigDTO.setSourceTableId(fromId);
                                    bloodConfigDTO.setTargetTableId(toTableId);
                                    bloodConfigDTO.setStatus(1);
                                    bloodList.add(bloodConfigDTO);
                                }
                            } else {
                                BloodConfigDTO bloodConfigDTO = new BloodConfigDTO();
                                bloodConfigDTO.setSourceDatasourceId(datasourceId);
                                bloodConfigDTO.setTargetDatasourceId(datasourceId);
                                bloodConfigDTO.setSourceTableId(fromTableId);
                                bloodConfigDTO.setTargetTableId(toTableId);
                                bloodConfigDTO.setStatus(1);
                                bloodList.add(bloodConfigDTO);
                            }

                            if (!hasInsert) {// 如果第一个不是Insert，则不需要解析此sql
                                break;
                            }
                        }

                    }

                    // 关联字段 解析数据表之间的字段的关联关系 TODO 未实现

                    Set<Relationship> columnSet = visitor.getRelationships();
                    logger.debug("解析数据表之间的字段的关联关系 " + columnSet.toString());
                    for (Iterator iterator = columnSet.iterator(); iterator.hasNext(); ) {
                        Relationship column = (Relationship) iterator.next();
                        logger.debug("[Relationship]" + column.toString());
                        // 如果不是等于则不进行解析
                        if (!column.getOperator().equals("=")) {
                            continue;
                        }
                        String leftName = getTableNameFromName(column.getLeft().getTable());
                        String rightName = getTableNameFromName(column.getRight().getTable());

                        String leftTableId = dataTableMap.get(leftName.toUpperCase());

                        String rightTableId = dataTableMap.get(rightName.toUpperCase());

                        if (leftTableId == null || rightTableId == null) {
                            continue;
                        }
                    }

                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                BloodConfigDTO bloodConfigDTO = new BloodConfigDTO();
                bloodConfigDTO.setSourceDatasourceId(datasourceId);
                bloodConfigDTO.setStatus(0);
                bloodList.add(bloodConfigDTO);
            }
        }
        return bloodList;
    }

    private static List<BloodConfigDTO> handleFieldSQL(List<String> sqlList, DbType dbType, String datasourceId) {
        List<BloodConfigDTO> bloodList = new ArrayList<>();
        Map<String, List<String>> tempTableMap = new HashMap<>();
        Map<String, String> dataTableMap = new HashMap<>();
        Map<String, String> relationMap = new HashMap<>();
        Map<String, String> relationColumnMap = new HashMap<>();
        Map<String, String> dataColumnMap = new HashMap<>();
        for (String sql : sqlList) {
            if (StringUtils.isBlank(sql)) {
                continue;
            }
            try {

                List<SQLStatement> stmtList = SQLUtils.parseStatements(sql.toLowerCase(), dbType);
                for (SQLStatement sqlStatement : stmtList) {
                    SchemaStatVisitor schemaStatVisitor = SQLUtils.createSchemaStatVisitor(dbType);
                    sqlStatement.accept(schemaStatVisitor);

                    Map<TableStat.Name, TableStat> tables = schemaStatVisitor.getTables();
                    Collection<TableStat.Column> columns = schemaStatVisitor.getColumns();
                    List<BloodConfigDTO> insertList = new ArrayList<>();
                    boolean insert = false;
                    if (Objects.nonNull(tables)) {
                        //处理目标表
                        tables.forEach(((name, tableStat) -> {
                            if (tableStat.getCreateCount() > 0 || tableStat.getInsertCount() > 0) {
                                logger.info("to: table[{}]", name.getName().toLowerCase());
                                columns.stream().filter(column -> Objects.equals(column.getTable().toLowerCase(), name.getName().toLowerCase())).forEach(column -> {
                                    logger.info("to: table[{}] column[{}]", column.getTable().toLowerCase(), column.getName().toLowerCase());
                                    BloodConfigDTO bloodConfigDTO = new BloodConfigDTO();
                                    bloodConfigDTO.setTargetTableCode(column.getTable().toLowerCase());
                                    bloodConfigDTO.setTargetFieldCode(column.getName().toLowerCase());
                                    insertList.add(bloodConfigDTO);
                                });
                                //处理未写插入字段的情况
                                if(insertList.isEmpty()){

                                }
                            }
                        }));
                        //处理源表
                        tables.forEach(((name, tableStat) -> {
                            if (tableStat.getSelectCount() > 0) {
                                logger.info("from: table[{}]", name.getName().toLowerCase());
                                columns.stream().filter(column -> Objects.equals(column.getTable().toLowerCase(), name.getName().toLowerCase())).forEach(column -> {
                                    logger.info("from: table[{}] column[{}]", column.getTable().toLowerCase(), column.getName().toLowerCase());

                                });
                            }
                        }));
                    }
                }



            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    private static String getColumnNameFromName(String name) {

        // 先处理是否有字段
        if (name.contains(".")) {
            String str[] = name.split("\\.");
            if (str.length == 3) {
                name = str[2];
            } else if (str.length == 2) {
                name = str[1];
            } else {
                name = str[0];
            }

        }

        return name;
    }

    private static String getTableNameFromName(String name) {
        if (name == null) {
            return null;
        }
        // 处理表名带引号"";
        name = name.replaceAll("\"", "");
        // 先处理是否有字段
        if (name.contains(".")) {
            String str[] = name.split("\\.", 2);
            name = str[1];
        } else if (name.contains("@")) {
            String str[] = name.split("@", 2);
            name = str[0];
        }

        return name;
    }


    private static List<BloodConfigDTO> analyseSparkFLowProcessNodeList(ProcessData processData) {

        //TODO 暂时先到数据库和表级别
        List<TaskNode> taskNodes = processData.getTasks();
        //获取输入节点
        List<TaskNode> inputNodes = getTaskNodesByType(taskNodes, 1);
        //获取输出节点
        List<TaskNode> outputNodes = getTaskNodesByType(taskNodes, 2);
        //数据血缘关系列表
        List<BloodConfigDTO> bloodList = new ArrayList<>();
        //判断处理到数据库级别
        Map<String, String> bloodDatabaseMap = new HashMap<>();
        try {
            if (inputNodes.isEmpty() && outputNodes.isEmpty()) {
                //无输入、输出节点
                return new ArrayList<>();
            } else if (inputNodes.isEmpty() && !outputNodes.isEmpty()) {
                //只有输出节点
                for (TaskNode taskNode : outputNodes) {
                    BloodConfigDTO bloodConfigDTO = handleOutputNode(taskNode, new HashMap<>(), new HashMap<>());

                    bloodList.add(bloodConfigDTO);

                }
            } else if (!inputNodes.isEmpty() && outputNodes.isEmpty()) {
                //只有输入节点
                for (TaskNode taskNode : inputNodes) {
                    BloodConfigDTO bloodConfigDTO = handleInputNode(taskNode, new HashMap<>(), new HashMap<>());
                    bloodList.add(bloodConfigDTO);

                }
            } else {
                DAG<String, TaskNode, String> dag = createDAG(taskNodes);
                //从输入到输出连线中，使用过的输出节点
                Map<String, TaskNode> endNodeMap = new HashMap<>();
                handleStartNodes(dag, inputNodes, endNodeMap, bloodList);
                //未被连接的输出节点
                outputNodes.removeAll(endNodeMap.values());
                for (TaskNode taskNode : outputNodes) {
                    BloodConfigDTO bloodConfigDTO = handleOutputNode(taskNode, new HashMap<>(), new HashMap<>());
                    bloodList.add(bloodConfigDTO);
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }


        return bloodList;
    }


    //处理输入节点
    private static void handleStartNodes(DAG<String, TaskNode, String> dag, List<TaskNode> startNodes, Map<String, TaskNode> endNodeMap, List<BloodConfigDTO> bloodList) {
        List<String> nodeNameList = new ArrayList<>();
        for (TaskNode node : startNodes) {
            nodeNameList.add(node.getName());
            handleNodes(dag, node, endNodeMap, nodeNameList, bloodList);
            nodeNameList.remove(node.getName());

        }
    }

    //递归处理节点
    private static void handleNodes(DAG<String, TaskNode, String> dag, TaskNode startNode, Map<String, TaskNode> endNodeMap, List<String> nodeNameList, List<BloodConfigDTO> bloodList) {

        Set<String> subTaskNodes = null;
        //获取当前节点连接的下一级节点列表
        subTaskNodes = dag.getSubsequentNodes(startNode.getName());

        for (String subNodeName : subTaskNodes) {
            //每次递归进来，先把节点名称放入列表，处理完后删除，以方便形成从输入到输出的完整流向列表
            nodeNameList.add(subNodeName);
            TaskNode subNode = dag.getNode(subNodeName);
            //是否是输出节点
            if (subNode.getNodeType() == 2) {
                //把处理过的节点放入map中，以便最后处理未连线的输出节点
                endNodeMap.put(subNode.getName(), subNode);
                //处理输入输出表的映射
                handleBloodRelation(dag, nodeNameList, bloodList);
            }
            //递归处理当前节点的下一级连接节点
            handleNodes(dag, subNode, endNodeMap, nodeNameList, bloodList);
            //删除当前节点的信息
            nodeNameList.remove(subNode.getName());
        }
    }

    private static void handleBloodRelation(DAG<String, TaskNode, String> dag, List<String> nodeNameList, List<BloodConfigDTO> bloodList) {

        Map<String, Object> relationMap = new HashMap<>();
        Map<String, String> fieldMap = new HashMap<>();
        for (int i = 0; i < nodeNameList.size(); i++) {
            String name = nodeNameList.get(i);
            TaskNode node = dag.getNode(name);
            //输入节点
            if (node.getNodeType() == 1) {
                //输入节点
                handleInputNode(node, relationMap, fieldMap);
            } else {
                //输出节点
                handleOutputNode(node, relationMap, fieldMap);
            }

        }
        //处理最终的字段连接信息
        Set<String> fieldKeys = fieldMap.keySet();
        String sourceDatasourceId = MapUtils.getString(relationMap, "sourceDatasourceId");
        String sourceTableCode = MapUtils.getString(relationMap, "sourceTableCode");
        String targetDatasourceId = MapUtils.getString(relationMap, "targetDatasourceId");
        String targetTableCode = MapUtils.getString(relationMap, "targetTableCode");
        for (String from : fieldKeys) {
            String to = fieldMap.get(from);
            BloodConfigDTO bloodConfigDTO = new BloodConfigDTO();
            bloodConfigDTO.setSourceDatasourceId(sourceDatasourceId);
            bloodConfigDTO.setSourceTableCode(sourceTableCode);
            bloodConfigDTO.setTargetDatasourceId(targetDatasourceId);
            bloodConfigDTO.setTargetTableCode(targetTableCode);
            bloodConfigDTO.setSourceFieldCode(from);
            bloodConfigDTO.setTargetFieldCode(to);
            bloodConfigDTO.setStatus(1);
            bloodList.add(bloodConfigDTO);
        }


    }

    private static BloodConfigDTO handleInputNode(TaskNode node, Map<String, Object> relationMap, Map<String, String> fieldMap) {
        String params = node.getParams();
        String outputData = node.getOutputData();
        Map<String, Object> paramsMap = JSONUtils.toObjectMap(params);
        String bundle = MapUtils.getString(paramsMap, "bundle", "");
        String settingParams = MapUtils.getString(paramsMap, "settingParams", "");
        Map<String, Object> settingMap = JSONUtils.toObjectMap(settingParams);
        List<Map<String, Object>> outputList = JSONUtils.toListMap(outputData);
        BloodConfigDTO bloodConfigDTO = new BloodConfigDTO();
        try {
            if (bundle.equals("avicit.bdp.bundle.common.JdbcSource")) {
                String value = MapUtils.getString(settingMap, "tableId", "");
                String tmp[] = value.split(",");
                if (tmp.length == 2) {
                    relationMap.put("sourceDatasourceId", tmp[0]);
                    relationMap.put("sourceTableCode", tmp[1]);
                    bloodConfigDTO.setSourceDatasourceId(tmp[0]);
                    bloodConfigDTO.setSourceFieldCode(tmp[1]);
                    //单独处理时，状态为非血缘关系
                    bloodConfigDTO.setStatus(0);
                }
                for (Map<String, Object> map : outputList) {
                    String fieldName = MapUtils.getString(map, "name");
                    //增加输入字段映射
                    fieldMap.put(fieldName, fieldName);
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }


        return bloodConfigDTO;

    }

    private static BloodConfigDTO handleOutputNode(TaskNode node, Map<String, Object> relationMap, Map<String, String> fieldMap) {
        String params = node.getParams();
        Map<String, Object> paramsMap = JSONUtils.toObjectMap(params);
        String bundle = MapUtils.getString(paramsMap, "bundle", "");
        String settingParams = MapUtils.getString(paramsMap, "settingParams", "");
        Map<String, Object> settingMap = JSONUtils.toObjectMap(settingParams);
        BloodConfigDTO bloodConfigDTO = new BloodConfigDTO();
        try {
            if (bundle.equals("avicit.bdp.bundle.common.JdbcSink")) {
                String tableId = MapUtils.getString(settingMap, "tableId", "");
                String tmp[] = tableId.split(",");
                if (tmp.length == 2) {
                    relationMap.put("targetDatasourceId", tmp[0]);
                    relationMap.put("targetTableCode", tmp[1]);
                    bloodConfigDTO.setSourceDatasourceId(tmp[0]);
                    bloodConfigDTO.setSourceFieldCode(tmp[1]);
                    //单独处理时，状态为非血缘关系
                    bloodConfigDTO.setStatus(0);
                }
            }
            Map<String, String> fieldMapNew = new HashMap<>();
            //处理输出映射字段
            String columnReflect = MapUtils.getString(settingMap, "columnReflect", "");

            if (StringUtils.isNotBlank(columnReflect)) {
                //兼容旧版本以冒号隔开
                if (columnReflect.trim().startsWith("[")) {
                    List<Map<String, Object>> reflectList = JSONUtils.toListMap(columnReflect);
                    for (Map<String, Object> map : reflectList) {
                        String inFieldName = MapUtils.getString(map, "inName");
                        String outFieldName = MapUtils.getString(map, "outName");
                        if (StringUtils.isNotBlank(inFieldName) && fieldMap.containsValue(inFieldName)) {
                            //根据上一次字段转换值，获取初始字段名称
                            String key = getKeyFromMapValue(fieldMap, inFieldName);
                            if (StringUtils.isNotBlank(key)) {
                                //重新设置输入字段和输出字段的映射
                                fieldMapNew.put(key, outFieldName);
                            }

                        }
                    }

                } else {
                    //旧版本格式   aa:bb,cc:dd
                    String[] fieldReflects = columnReflect.split(",");
                    for (String fields : fieldReflects) {
                        String[] field = fields.split(":");
                        if (field.length == 2) {
                            String outFieldName = field[0];
                            String inFieldName = field[1];
                            //根据上一次字段转换值，获取初始字段名称
                            String key = getKeyFromMapValue(fieldMap, inFieldName);
                            if (StringUtils.isNotBlank(key)) {
                                //重新设置输入字段和输出字段的映射
                                fieldMapNew.put(key, outFieldName);
                            }
                        }
                    }

                }
            }
            //清空输入的记录，并把新生成的字段连接信息放到原map中
            fieldMap.clear();
            fieldMap.putAll(fieldMapNew);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

        return bloodConfigDTO;
    }

    private static String getKeyFromMapValue(Map<String, String> map, String value) {
        for (Map.Entry<String, String> entry : map.entrySet()) {
            String mapKey = entry.getKey();
            String mapValue = entry.getValue();
            if (value.equals(mapValue)) {
                return mapKey;
            }
        }
        return null;
    }


    //处理节点成DAG图
    private static DAG<String, TaskNode, String> createDAG(List<TaskNode> taskNodeResponseList) {
        DAG<String, TaskNode, String> graph = new DAG<>();

        // Fill the vertices
        for (TaskNode taskNodeResponse : taskNodeResponseList) {
            graph.addNode(taskNodeResponse.getName(), taskNodeResponse);
        }

        // Fill edge relations
        for (TaskNode taskNodeResponse : taskNodeResponseList) {
            List<String> preTasks = JSONUtils.toList(taskNodeResponse.getPreTasks(), String.class);
            if (CollectionUtils.isNotEmpty(preTasks)) {
                for (String preTask : preTasks) {
                    graph.addEdge(preTask, taskNodeResponse.getName());
                }
            }
        }

        return graph;
    }


    private static List<TaskNode> getTaskNodesByType(List<TaskNode> taskNodes, Integer nodeType) {
        List<TaskNode> list = new ArrayList<>();
        for (TaskNode taskNode : taskNodes) {
            if (nodeType.equals(taskNode.getNodeType())) {
                list.add(taskNode);
            }
        }
        return list;
    }
}
